package com.chat.login.controller;

import com.chat.common.entity.Version;
import com.chat.common.vo.R;
import com.chat.login.annotate.IsNumeric;
import com.chat.login.domain.dto.ForgotPasswordDTO;
import com.chat.login.domain.dto.UserAppealDTO;
import com.chat.login.domain.dto.UserFeedbackDTO;
import com.chat.login.domain.vo.VersionNumberVO;
import com.chat.login.service.IUserService;
import com.chat.login.service.IVersionService;
import jakarta.activation.MimetypesFileTypeMap;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;


/**
 * AuthUser
 */
@RestController
@Validated
@RequestMapping("/auth/user")
@Slf4j
public class UserController {
    @Autowired
    IUserService userService;

    @Autowired
    IVersionService iVersionService;

    /**
     * 重置密码
     * @param forgotPasswordDTO
     * @return
     */
    @PostMapping("/resetPassword")
    public R ResetPassword(@RequestBody ForgotPasswordDTO forgotPasswordDTO) {
        return userService.resetPassword(forgotPasswordDTO);
    }

    /**
     * 申述
     * @param userAppealDTO
     * @return
     */
    @PostMapping("/user_appeal")
    public R UserAppeal(@RequestBody UserAppealDTO userAppealDTO) {
        return userService.userAppeal(userAppealDTO);
    }

    /**
     * 获取账号的冻结原因
     * @param account
     * @return
     */
    @GetMapping("/getAccountDisable")
    public R getAccountDisable(@RequestParam @NotBlank(message = "账号不能为空") @IsNumeric(message = "账号不是数字") String account){
        return userService.getAccountDisable(account);
    }

    /**
     * 根据账号获取反馈列表
     * @param account
     * @return
     */
    @GetMapping("/getAccountFeedback")
    public R getAccountFeedback(@RequestParam @NotBlank(message = "账号不能为空") @IsNumeric(message = "账号不是数字") String account){
        return userService.getAccountUserFeedbackList(account);
    }

    /**
     * 用户反馈
     * @param userFeedbackDTO
     * @return
     */
    @PostMapping("/user_feedback")
    public R UserFeedback(@RequestBody UserFeedbackDTO userFeedbackDTO) {
        return userService.addOneUserFeedback(userFeedbackDTO);
    }

    /**
     * 获取最新版本的版本号
     * @return
     */
    @GetMapping("/news-version-number")
    public R<VersionNumberVO> getNewVersion(){
        return userService.getNewVersion();
    }

    /**
     * 获取最新的版本文件
     * @return
     */
    @GetMapping("/downloadFile/news-version")
    public ResponseEntity<InputStreamResource> downloadFile() {
        try {
            Version newVersion = iVersionService.getNewVersion();
            String fileUrl = newVersion.getVersionUrl();
            //String extension = fileUrl.substring(fileUrl.lastIndexOf("."));
            //String fileName = "E-chat_" + newVersion.getVersionNumber() + extension;
            //写死成msi
            String fileName = "E-chat_" + newVersion.getVersionNumber() + ".msi";

            // 计算文件类型
            MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
            String mimeType = fileTypeMap.getContentType(fileName);

            // 准备 HTTP 头
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");
            headers.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
            headers.add(HttpHeaders.PRAGMA, "no-cache");
            headers.add(HttpHeaders.EXPIRES, "0");
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

            // 使用 OkHttpClient 获取文件的 InputStream
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder().url(fileUrl).build();
            log.info("开始下载文件: {}", fileUrl);
            Response response = client.newCall(request).execute();
            String contentLength = response.header("Content-Length");
            headers.add(HttpHeaders.CONTENT_LENGTH, contentLength);

            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

            InputStream inputStream = response.body().byteStream();
            InputStreamResource inputStreamResource = new InputStreamResource(inputStream);

            log.info("文件下载完成: {}", fileUrl);

            // 返回 ResponseEntity 包含 InputStreamResource
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentType(MediaType.parseMediaType(mimeType))
                    .body(inputStreamResource);

        } catch (Exception e) {
            // 日志记录错误，此处的处理简化了
            e.printStackTrace();
            log.error("下载文件时出错: {}", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    //@GetMapping("/download")
    public ResponseEntity<InputStreamResource> downloadFile(@RequestHeader(value = "Range", required = false) String rangeHeader) {
        try {
            // 获取最新版本的信息
            Version newVersion = iVersionService.getNewVersion();
            String fileUrl = newVersion.getVersionUrl();
            String fileName = "E-chat_" + newVersion.getVersionNumber() + ".msi";

            // 计算文件的MIME类型
            MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
            String mimeType = fileTypeMap.getContentType(fileName);

            // 创建一个 OkHttpClient 实例来发起请求
            OkHttpClient client = new OkHttpClient();
            Request.Builder builder = new Request.Builder().url(fileUrl);
            // 如果存在 Range 头，添加到请求中
            if (rangeHeader != null) {
                builder.addHeader("Range", rangeHeader);
            }
            Request request = builder.build();

            // 发起请求并获取响应
            Response response = client.newCall(request).execute();

            // 确认响应成功，否则抛出异常
            if (!response.isSuccessful()) {
                throw new IOException("服务器响应失败: " + response);
            }

            long contentLength = response.body().contentLength();
            InputStream inputStream = response.body().byteStream();

            // 准备 HTTP 响应的头部信息
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");
            headers.add(HttpHeaders.ACCEPT_RANGES, "bytes");
            headers.add(HttpHeaders.CONTENT_TYPE, mimeType);
            headers.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
            headers.add(HttpHeaders.PRAGMA, "no-cache");
            headers.add(HttpHeaders.EXPIRES, "0");

            // Range 请求处理
            if (rangeHeader != null) {
                // 提取实际返回的内容范围
                String contentRange = response.header("Content-Range");
                long startByte = 0;
                if (contentRange != null) {
                    startByte = Long.parseLong(contentRange.substring(contentRange.indexOf(' ') + 1, contentRange.indexOf('-')));
                }
                headers.add(HttpHeaders.CONTENT_RANGE, contentRange);
                headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(contentLength - startByte));
                // 返回部分内容的HTTP状态码
                return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
                        .headers(headers)
                        .body(new InputStreamResource(inputStream));
            }

            // 全部内容的下载处理
            headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(contentLength));
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentType(MediaType.parseMediaType(mimeType))
                    .body(new InputStreamResource(inputStream));

        } catch (Exception e) {
            // 简化的异常处理，实际应该更详细地记录异常信息
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}
